using System;
using System.Collections;
using System.Globalization;
using System.Reflection;
using System.Text;

namespace Microsoft.SqlServer.Tools.PublishWizard.CommandLine
{
	internal class Argument
	{
		private string longName;

		private string shortName;

		private string helpText;

		private string helpTopic;

		private bool hasHelpText;

		private bool explicitShortName;

		private object defaultValue;

		private bool seenValue;

		private PropertyInfo property;

		private Type elementType;

		private ArgumentTypes flags;

		private ArrayList collectionValues;

		private ErrorReporter reporter;

		private bool isDefault;

		private string argumentHelpText;

		private bool hasArgumentHelpText;

		private short _maxNumberOfArguments;

		public Type ValueType
		{
			get
			{
				if (!this.IsCollection)
				{
					return this.Type;
				}
				return this.elementType;
			}
		}

		public string LongName
		{
			get
			{
				return this.longName;
			}
		}

		public bool ExplicitShortName
		{
			get
			{
				return this.explicitShortName;
			}
		}

		public string ShortName
		{
			get
			{
				return this.shortName;
			}
		}

		public bool HasShortName
		{
			get
			{
				return this.shortName != null;
			}
		}

		public bool HasHelpText
		{
			get
			{
				return this.hasHelpText;
			}
		}

		public string HelpTopic
		{
			get
			{
				return this.helpTopic;
			}
		}

		public string HelpText
		{
			get
			{
				return this.helpText;
			}
		}

		public object DefaultValue
		{
			get
			{
				return this.defaultValue;
			}
		}

		public bool HasDefaultValue
		{
			get
			{
				return null != this.defaultValue;
			}
		}

		public short MaxNumberOfArguments
		{
			get
			{
				return this._maxNumberOfArguments;
			}
		}

		public string FullHelpText
		{
			get
			{
				if (this.HasDefaultValue)
				{
					return string.Format(CultureInfo.CurrentCulture, CommandLineResources.DefaultValueHelpText, new object[]
					{
						this.HelpText,
						this.DefaultValue
					});
				}
				return this.HelpText;
			}
		}

		public string SyntaxHelp
		{
			get
			{
				StringBuilder stringBuilder = new StringBuilder();
				if (this.IsDefault)
				{
					stringBuilder.Append("<");
					stringBuilder.Append(this.LongName);
					stringBuilder.Append(">");
				}
				else
				{
					stringBuilder.Append("[");
					stringBuilder.Append("-");
					stringBuilder.Append(this.LongName);
					if (this.hasArgumentHelpText)
					{
						stringBuilder.Append(" " + this.argumentHelpText);
					}
					stringBuilder.Append("] : ");
				}
				return stringBuilder.ToString();
			}
		}

		public bool IsRequired
		{
			get
			{
				return ArgumentTypes.None != (this.flags & ArgumentTypes.Required);
			}
		}

		public bool SeenValue
		{
			get
			{
				return this.seenValue;
			}
		}

		public bool AllowMultiple
		{
			get
			{
				return ArgumentTypes.None != (this.flags & ArgumentTypes.Multiple);
			}
		}

		public bool Unique
		{
			get
			{
				return ArgumentTypes.None != (this.flags & ArgumentTypes.Unique);
			}
		}

		public Type Type
		{
			get
			{
				return this.property.PropertyType;
			}
		}

		public bool IsCollection
		{
			get
			{
				return Parser.IsCollectionType(this.Type);
			}
		}

		public bool IsDefault
		{
			get
			{
				return this.isDefault;
			}
		}

		public string ArgumentHelpText
		{
			get
			{
				return this.argumentHelpText;
			}
		}

		public Argument(ArgumentAttribute attribute, PropertyInfo property, ErrorReporter reporter)
		{
			this.longName = Parser.LongName(attribute, property);
			this.explicitShortName = Parser.ExplicitShortName(attribute);
			this.shortName = Parser.ShortName(attribute, property);
			this.hasHelpText = Parser.HasHelpText(attribute);
			this.helpText = Parser.HelpText(attribute);
			this.helpTopic = Parser.HelpTopic(attribute);
			this.defaultValue = Parser.DefaultValue(attribute);
			this.elementType = Parser.ElementType(attribute, property);
			this.flags = Parser.Flags(attribute, property);
			this.property = property;
			this.reporter = reporter;
			this._maxNumberOfArguments = Parser.MaxNumberOfArguments(attribute);
			this.argumentHelpText = Parser.ArgumentHelpText(attribute);
			if (!string.IsNullOrEmpty(this.argumentHelpText))
			{
				this.hasArgumentHelpText = true;
			}
			this.isDefault = (attribute != null && attribute.IsDefaultArgument);
			if (this.IsCollection)
			{
				this.collectionValues = new ArrayList();
			}
		}

		public void ClearShortName()
		{
			this.shortName = null;
		}

		public bool Finish(object destination)
		{
			if (!this.SeenValue && this.HasDefaultValue)
			{
				this.property.SetValue(destination, this.DefaultValue, null);
			}
			if (this.IsCollection)
			{
				ArrayList arrayList = (ArrayList)this.property.GetValue(destination, null);
				arrayList.Clear();
				foreach (object current in this.collectionValues)
				{
					arrayList.Add(current);
				}
			}
			return this.ReportMissingRequiredArgument();
		}

		public bool SetValue(string value, object destination)
		{
			if (this.SeenValue && !this.AllowMultiple)
			{
				this.reporter(string.Format(CultureInfo.CurrentCulture, CommandLineResources.DuplicateArgument, new object[]
				{
					this.LongName
				}));
				return false;
			}
			this.seenValue = true;
			object obj;
			if (!this.ParseValue(this.ValueType, value, out obj))
			{
				return false;
			}
			if (this.IsCollection)
			{
				if (this.Unique && this.collectionValues.Contains(obj))
				{
					this.ReportDuplicateArgumentValue(value);
					return false;
				}
				this.collectionValues.Add(obj);
			}
			else
			{
				this.property.SetValue(destination, obj, null);
			}
			return true;
		}

		private bool ReportMissingRequiredArgument()
		{
			if (this.IsRequired && !this.SeenValue)
			{
				if (this.IsDefault)
				{
					this.reporter(string.Format(CultureInfo.CurrentCulture, CommandLineResources.MissingRequiredArgument + " '<{0}>'.", new object[]
					{
						this.LongName
					}));
				}
				else
				{
					this.reporter(string.Format(CultureInfo.CurrentCulture, CommandLineResources.MissingRequiredArgument + " '/{0}'.", new object[]
					{
						this.LongName
					}));
				}
				return true;
			}
			return false;
		}

		private void ReportDuplicateArgumentValue(string value)
		{
			this.reporter(string.Format(CultureInfo.CurrentCulture, CommandLineResources.DuplicateArgument + " '{1}'", new object[]
			{
				this.LongName,
				value
			}));
		}

		private void ReportBadArgumentValue(string value)
		{
			this.reporter(string.Format(CultureInfo.CurrentCulture, CommandLineResources.InvalidValueforCommandLineOption, new object[]
			{
				value,
				this.LongName
			}));
		}

		private bool ParseValue(Type type, string stringData, out object value)
		{
			if (stringData != null || type == typeof(bool))
			{
				if (stringData != null)
				{
					if (stringData.Length <= 0)
					{
						goto IL_E0;
					}
				}
				try
				{
					if (type == typeof(string))
					{
						value = stringData;
						bool result = true;
						return result;
					}
					if (type == typeof(bool))
					{
						if (stringData == null || stringData == "+")
						{
							value = true;
							bool result = true;
							return result;
						}
						if (stringData == "-")
						{
							value = false;
							bool result = true;
							return result;
						}
					}
					else
					{
						bool result;
						if (type == typeof(int))
						{
							value = int.Parse(stringData, CultureInfo.CurrentCulture);
							result = true;
							return result;
						}
						if (type == typeof(uint))
						{
							value = int.Parse(stringData, CultureInfo.CurrentCulture);
							result = true;
							return result;
						}
						value = Enum.Parse(type, stringData, true);
						result = true;
						return result;
					}
				}
				catch (FormatException)
				{
				}
				catch (ArgumentNullException)
				{
				}
				catch (ArgumentException)
				{
				}
				catch (OverflowException)
				{
				}
			}
			IL_E0:
			this.ReportBadArgumentValue(stringData);
			value = null;
			return false;
		}
	}
}
